package cn.huiyunche.base.service.interfaces.impl;

import cn.huiyunche.base.service.enums.AvailableEnum;
import cn.huiyunche.base.service.enums.DUserOilCardStatusEnum;
import cn.huiyunche.base.service.enums.DWaybillStatusEnum;
import cn.huiyunche.base.service.enums.UserTypeEnum;
import cn.huiyunche.base.service.interfaces.TmsDUserService;
import cn.huiyunche.base.service.mappers.*;
import cn.huiyunche.base.service.mappers.ext.DUserViewMapper;
import cn.huiyunche.base.service.model.*;
import cn.huiyunche.base.service.vo.DUserVo;
import cn.huiyunche.base.service.vo.PageVo;
import cn.huiyunche.tools.basic.exceptions.BusinessException;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

@Service
public class TmsDUserServiceImpl implements TmsDUserService {

    private static final Logger LOGGER = LoggerFactory.getLogger(TmsDUserServiceImpl.class);

    @Autowired
    private DUserViewMapper dUserViewMapper = null;

    @Autowired
    private DUserMapper dUserMapper = null;

    @Autowired
    private SUserMapper sUserMapper = null;

    @Autowired
    private DUserExtMapper dUserExtMapper = null;

    @Autowired
    private DWaybillMapper dWaybillMapper = null;

    @Autowired
    private DUserOilcardMapper dUserOilcardMapper = null;

    private DUserOilcardMapper getDUserOilcardMapper() {
        return this.dUserOilcardMapper;
    }

    private DWaybillMapper getDWaybillMapper() {
        return this.dWaybillMapper;
    }

    private DUserExtMapper getDUserExtMapper() {
        return this.dUserExtMapper;
    }

    private DUserMapper getDUserMapper() {
        return this.dUserMapper;
    }

    private SUserMapper getSUserMapper() {
        return this.sUserMapper;
    }

    private DUserViewMapper getDUserViewMapper() {
        return this.dUserViewMapper;
    }

    @Override
    public Map<String, Object> userList(PageVo pageVo, DUserVo dUserVo) throws Exception {
        LOGGER.info("user list DUserVo: {}, PageVo: {}", dUserVo, pageVo);
        pageVo.setTotalRecord(this.getDUserViewMapper().countByExample(dUserVo, pageVo));
        Map<String, Object> map = new HashMap<>();
        List<DUserVo> dVos = this.getDUserViewMapper().selectByExample(dUserVo, pageVo);
        if (CollectionUtils.isNotEmpty(dVos)) {
            dVos.parallelStream().forEach(value -> {
                // 统计用户出车记录
                try {
                    value.setDisRecord(this.statisticWaybill(value.getsId()));
                    // 用户状态
                    int res = this.userStatus(value.getsId());
                    if (res > 0) {
                        value.setStatus("在途");
                    } else {
                        value.setStatus("空闲");
                    }
                    // 用户绑定油卡状态
                    List<DUserOilcard> oilCards = this.bindOilCard(value.getsId());
                    if (CollectionUtils.isNotEmpty(oilCards)) {
                        value.setBindStatus(oilCards.get(0).getStatus());
                    } else {
                        value.setBindStatus("40");//未绑
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            });
        }
        map.put("driver", dVos);
        map.put("page", pageVo);
        return map;
    }

    /**
     * 统计出车记录
     *
     * @param userId
     * @return
     * @throws BusinessException
     */
    private int statisticWaybill(Long userId) throws Exception {
        LOGGER.info("statisticWaybill params userId: {}", userId);
        if (null == userId || userId == 0) {
            LOGGER.info("current user id is not null");
            throw new BusinessException("当前用户不合法");
        }
        DWaybillExample example = new DWaybillExample();
        example.createCriteria().andUserIdEqualTo(userId).andWaybillStatusEqualTo(DWaybillStatusEnum.COMPLETED.getValue());
        List<DWaybill> lists = this.getDWaybillMapper().selectByExample(example);
        if (CollectionUtils.isNotEmpty(lists)) {
            return lists.size();
        }
        return 0;
    }

    /**
     * 用户状态
     *
     * @param userId
     * @return
     * @throws BusinessException
     */
    private int userStatus(Long userId) throws Exception {
        LOGGER.info("userStatus params userId: {}", userId);
        if (null == userId || userId == 0) {
            LOGGER.info("current user id is not null");
            throw new BusinessException("当前用户不合法");
        }
        List<Integer> statuss = new ArrayList<>();
        statuss.add(DWaybillStatusEnum.DEPARTURE.getValue());
        statuss.add(DWaybillStatusEnum.INTRANSIT.getValue());
        statuss.add(DWaybillStatusEnum.DEAL_CAR.getValue());
        DWaybillExample example = new DWaybillExample();
        example.createCriteria().andUserIdEqualTo(userId).andWaybillStatusIn(statuss);
        List<DWaybill> lists = this.getDWaybillMapper().selectByExample(example);
        if (CollectionUtils.isNotEmpty(lists)) {
            return lists.size();
        }
        return 0;
    }

    /**
     * 查询司机油卡
     *
     * @param userId
     * @return
     * @throws BusinessException
     */
    private List<DUserOilcard> bindOilCard(Long userId) throws Exception {
        LOGGER.info("bindOilCard params userId: {}", userId);
        DUserOilcardExample example = new DUserOilcardExample();
        example.setOrderByClause("id desc");
        example.createCriteria().andUserIdEqualTo(userId);
        return this.getDUserOilcardMapper().selectByExample(example);
    }

    @Override
    public int disabled(Long sId, Long dId) throws Exception {
        LOGGER.info("disabled user sId: {}, dId: {}", sId, dId);
        return modifyStatus(sId, dId, AvailableEnum.F.getValue());
    }

    @Override
    public int enabled(Long sId, Long dId) throws Exception {
        LOGGER.info("enabled user sId: {}, dId: {}", sId, dId);
        return modifyStatus(sId, dId, AvailableEnum.T.getValue());
    }

    // 修改用户是否启用
    private int modifyStatus(Long sId, Long dId, String available) throws Exception {
        if (sId == null) {
            LOGGER.info("user id is not null");
            throw new BusinessException("用户ID不能为空");
        }
        SUser sUser = this.getSUserMapper().selectByPrimaryKey(sId);
        if (sUser == null) {
            LOGGER.info("user info is null");
            throw new BusinessException("用户信息不存在！");
        }
        sUser.setEnable(available);
        return this.getSUserMapper().updateByPrimaryKeySelective(sUser);
    }

    @Override
    public int modifyPhone(Long sId, Long dId, String phone) throws Exception {
        LOGGER.info("modifyPhone user sId: {}, dId: {}, phone", sId, dId, phone);
        if (sId == null || dId == null) {
            LOGGER.info("user id is not null");
            throw new BusinessException("用户ID不能为空");
        }
        SUser sUser = this.getSUserMapper().selectByPrimaryKey(sId);
        DUser dUser = this.getDUserMapper().selectByPrimaryKey(dId);
        DUserExtExample example = new DUserExtExample();
        example.createCriteria().andUserIdEqualTo(dId);
        List<DUserExt> lists = this.getDUserExtMapper().selectByExample(example);
        if (sUser == null || dUser == null) {
            LOGGER.info("user info is null");
            throw new BusinessException("用户信息不存在！");
        }
        // 判断手机号是否存在
        SUserExample userExample = new SUserExample();
        userExample.createCriteria().andPhoneEqualTo(phone).andUserTypeEqualTo(UserTypeEnum.SEND_DRIVER.getValue())
                .andIdNotEqualTo(sId);
        List<SUser> sList = this.getSUserMapper().selectByExample(userExample);
        if (CollectionUtils.isNotEmpty(sList)) {
            LOGGER.info("phone is exist");
            throw new BusinessException("手机号已存在");
        }
        // 更新SUser数据
        SUser user = new SUser();
        user.setId(sId);
        user.setPhone(phone);
        int res = this.getSUserMapper().updateByPrimaryKeySelective(user);
        // 更新DUser数据
        DUser du = new DUser();
        du.setId(dId);
        du.setLoginName(phone);
        this.getDUserMapper().updateByPrimaryKeySelective(du);
        if (CollectionUtils.isNotEmpty(lists)) {
            DUserExt dUserExt = lists.get(0);
            dUserExt.setPhone(phone);
            // 更新DUserExt数据
            this.getDUserExtMapper().updateByPrimaryKeySelective(dUserExt);
        }
        return res;
    }

    @Override
    public Long bindOilCard(Long sId, String oilCardCode) throws Exception {
        LOGGER.info("bindOilCard params sid: {}, bindOilCard: {}", sId, oilCardCode);
        if (null == sId || sId == 0) {
            LOGGER.info("sid is not null");
            throw new BusinessException("用户ID不能为空");
        } else if (StringUtils.isBlank(oilCardCode)) {
            LOGGER.info("oilCardCode is not null");
            throw new BusinessException("油卡卡号不能为空");
        }
        // 是否重复
        List<DUserOilcard> dVos = this.bindOilCard(sId);
        if (CollectionUtils.isNotEmpty(dVos)) {
            DUserOilcard duo = dVos.get(0);
            if (DUserOilCardStatusEnum.NORMAL.getValue().equals(duo.getStatus())) {
                throw new BusinessException("此司机已绑定油卡");
            }
        }
        DUserOilcard oilcard = new DUserOilcard();
        oilcard.setUserId(sId);
        oilcard.setCardCode(oilCardCode);
        oilcard.setUpdateTime(new Date());
        oilcard.setStatus(DUserOilCardStatusEnum.NORMAL.getValue());
        this.getDUserOilcardMapper().insertSelective(oilcard);
        return oilcard.getId();
    }

}